"""
态势对象关系管理 API 路由
"""
from typing import Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from src.situation.database import get_db
from src.situation.relationship_service import RelationshipService
from src.situation.graph_export_service import GraphExportService
from src.situation.relationship_schemas import (
    RelationshipCreate,
    RelationshipUpdate,
    RelationshipResponse,
    RelationshipListResponse,
    RelationshipFilter,
    RelationshipTreeNode,
    CycleCheckRequest,
    CycleCheckResponse,
    GraphExportRequest,
    GraphExportResponse,
)
from server.utils.auth_middleware import get_admin_user, get_required_user
from server.models.user_model import User
from src.utils import logger

relationship_router = APIRouter(prefix="/situation", tags=["situation-relationships"])


# ============================================================================
# === 关系管理 CRUD ===
# ============================================================================


@relationship_router.post("/relationships", response_model=RelationshipResponse)
async def create_relationship(rel_data: RelationshipCreate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """创建态势对象关系"""
    logger.info(f"[关系路由] 接收到创建关系请求")

    try:
        result = await RelationshipService.create_relationship(db, rel_data, user=current_user.username if current_user else None)
        logger.info(f"[关系路由] 关系创建成功: {result.id}")
        return result
    except ValueError as ve:
        logger.warning(f"[关系路由] 创建关系业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error(f"[关系路由] 创建关系系统错误: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"系统错误,创建失败: {str(e)}")


@relationship_router.get("/relationships", response_model=RelationshipListResponse)
async def list_relationships(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    source_object_id: Optional[UUID] = Query(None, description="源对象ID筛选"),
    target_object_id: Optional[UUID] = Query(None, description="目标对象ID筛选"),
    relationship_type: Optional[str] = Query(None, description="关系类型筛选"),
    relationship_level: Optional[int] = Query(None, ge=1, le=5, description="关系层级筛选"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_required_user),
):
    """获取关系列表(支持分页、筛选)"""
    logger.info(f"[关系路由] 接收到列表查询请求")

    try:
        filters = RelationshipFilter(source_object_id=source_object_id, target_object_id=target_object_id, relationship_type=relationship_type, relationship_level=relationship_level)
        result = await RelationshipService.list_relationships(db, page=page, page_size=page_size, filters=filters)
        logger.info(f"[关系路由] 查询成功: total={result.total}")
        return result
    except Exception as e:
        logger.error(f"[关系路由] 查询失败: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")


@relationship_router.get("/relationships/{relationship_id}", response_model=RelationshipResponse)
async def get_relationship(relationship_id: UUID, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_required_user)):
    """获取关系详情"""
    result = await RelationshipService.get_relationship(db, relationship_id)
    if not result:
        raise HTTPException(status_code=404, detail="关系不存在")
    return result


@relationship_router.put("/relationships/{relationship_id}", response_model=RelationshipResponse)
async def update_relationship(relationship_id: UUID, rel_data: RelationshipUpdate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """更新关系"""
    logger.info(f"[关系路由] 接收到更新关系请求: {relationship_id}")

    try:
        result = await RelationshipService.update_relationship(db, relationship_id, rel_data, user=current_user.username if current_user else None)
        if not result:
            raise HTTPException(status_code=404, detail="关系不存在")
        logger.info(f"[关系路由] 关系更新成功: {result.id}")
        return result
    except ValueError as ve:
        logger.warning(f"[关系路由] 更新关系业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[关系路由] 更新关系系统错误: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"系统错误,更新失败: {str(e)}")


@relationship_router.delete("/relationships/{relationship_id}")
async def delete_relationship(relationship_id: UUID, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """删除关系"""
    logger.info(f"[关系路由] 接收到删除关系请求: {relationship_id}")

    try:
        success = await RelationshipService.delete_relationship(db, relationship_id, user=current_user.username if current_user else None)
        if not success:
            raise HTTPException(status_code=404, detail="关系不存在")
        logger.info(f"[关系路由] 关系删除成功: {relationship_id}")
        return {"message": "删除成功", "id": str(relationship_id)}
    except ValueError as ve:
        logger.warning(f"[关系路由] 删除关系业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[关系路由] 删除关系系统错误: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"系统错误,删除失败: {str(e)}")


# ============================================================================
# === 关系树和循环检测 ===
# ============================================================================


@relationship_router.get("/relationships/tree/{root_object_id}", response_model=RelationshipTreeNode, include_in_schema=False)
async def get_relationship_tree(root_object_id: UUID, max_level: int = Query(5, ge=1, le=5, description="最大层级"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_required_user)):
    """
    获取关系树(递归查询子关系,最多5层)

    注意: 此端点从 OpenAPI schema 中排除,以避免递归模型导致的 MCP 服务器问题
    """
    logger.info(f"[关系路由] 接收到关系树查询请求: root={root_object_id}, max_level={max_level}")

    try:
        result = await RelationshipService.get_relationship_tree(db, root_object_id, max_level)
        logger.info(f"[关系路由] 关系树查询成功")
        return result
    except ValueError as ve:
        logger.warning(f"[关系路由] 关系树查询错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error(f"[关系路由] 关系树查询失败: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")


@relationship_router.post("/relationships/validate-cycle", response_model=CycleCheckResponse)
async def validate_cycle(request: CycleCheckRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_required_user)):
    """检测循环依赖"""
    logger.info(f"[关系路由] 接收到循环检测请求")

    try:
        result = await RelationshipService.check_cycle(db, request.source_object_id, request.target_object_id, request.relationship_type)
        logger.info(f"[关系路由] 循环检测完成: has_cycle={result.has_cycle}")
        return result
    except Exception as e:
        logger.error(f"[关系路由] 循环检测失败: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"检测失败: {str(e)}")


# ============================================================================
# === 知识图谱导出 ===
# ============================================================================


@relationship_router.post("/export-to-graph", response_model=GraphExportResponse)
async def export_to_knowledge_graph(request: GraphExportRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """导出态势对象及关系到 Neo4j 知识图谱"""
    logger.info(f"[知识图谱路由] 接收到导出请求")

    try:
        # 从环境变量获取 Neo4j 连接信息
        import os
        neo4j_uri = os.getenv("NEO4J_URI", "bolt://localhost:7687")
        neo4j_user = os.getenv("NEO4J_USERNAME", "neo4j")
        neo4j_password = os.getenv("NEO4J_PASSWORD", "0123456789")

        logger.info(f"[知识图谱路由] 连接 Neo4j: {neo4j_uri}")

        graph_service = GraphExportService(neo4j_uri=neo4j_uri, neo4j_user=neo4j_user, neo4j_password=neo4j_password)
        result = await graph_service.export_to_neo4j(db, request)

        logger.info(f"[知识图谱路由] 导出完成: {result.message}")
        return result
    except ConnectionError as ce:
        logger.error(f"[知识图谱路由] Neo4j 连接错误: {ce}")
        raise HTTPException(status_code=503, detail=str(ce))
    except Exception as e:
        logger.error(f"[知识图谱路由] 导出失败: {type(e).__name__}: {e}")
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")
